package model_controller;

import database_handler.DatabaseManager;
import help_util.DateTime;
import help_util.IndexConverter;
import its_models.expert_model.ExpertModel;
import its_models.expert_model.ExpertModelProperties;
import its_models.expert_model.expert_help_util.StrategyGraphUnit;
import its_models.expert_model.expert_help_util.StepsMatrix;
import its_models.student_model.StudentModel;
import its_models.tutor_model.TutorModel;
import java.util.ArrayList;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import sudoku_gameboard_structure.SudokuGameboard;
import sudoku_gui.SudokuComponentsProperties;
import sudoku_gui_handler.TimerHandler;
import sudoku_properties.BasicSudokuParam;
import sudoku_properties.SudokuGameInfoParam;
import java.io.*;
import java.net.*;

/************************************************************
 * Class ControlLayer
 * 1. Control functions between Layer
 ************************************************************/
public class ControlLayer {

    // 20091017 phrase2 start
    public ControlLayer() {

    }
    // 20091017 phrase2 end

    public ControlLayer(JApplet inputWebSudoku,JLabel[][][] inputCaluCellsLabel, JLabel[][] inputCellsValueLabel, JTextArea inputLearnerStepsMsgBox,
            JLabel inputSolvingStatus, JLabel inputGameStatus, JLabel[] inputHintsStatus, TimerHandler inputTimer,
            JPanel inputGameConclusionPane, SudokuGameboard inputGameboard, int inputLangMode){

        langMode = inputLangMode;
        studentModel = new StudentModel(this);
        expertModel = new ExpertModel(this);
        tutorModel = new TutorModel(this);
        /* initialize interface componenets */
        caluCellsLabel =  inputCaluCellsLabel;
        cellsValueLabel = inputCellsValueLabel;
        learnerStepsMsgBox = inputLearnerStepsMsgBox;
        SolvingStatus = inputSolvingStatus;
        GameStatus = inputGameStatus;
        HintsStatus = inputHintsStatus;
        Timer = inputTimer;
        // 2009P1T1 starts
        /* games variable*/
        puzzleID = 0;
        difficulty = null;
        rulesPriority = new String[LOGICAL_RULES.length];
        for(int i=0; i<rulesPriority.length; i++){
            rulesPriority[i] = null;
        }
        webSudoku = inputWebSudoku;
        // 2009P1T1 ends

        //20091112 phrase2 start
        Gameboard = inputGameboard;
        dbManager = new DatabaseManager(this);
        //20091112 phrase2 end

    }

    public JApplet getWebSudoku(){
        return webSudoku;
    }
    // 20091112 phrase2 start
    public int getTimeValueInSecond(){
        return Timer.getTimeValueInSecond();
    }
    // 20091112 phrase2 end

    // 2009P1T1 Starts
    /* game variables start **************************************************************/
    public void setPuzzleID(String inputPuzzleID){
        puzzleID = Integer.parseInt(inputPuzzleID);
    }
    public void setDifficulty(String inputDifficulty){
        difficulty = inputDifficulty;
    }
    public void setRulesPriority(String inputRules, int inputPriority){
        rulesPriority[inputPriority] = inputRules;
    }
    // 20091016 phrase2 start
    public void setUserID(int inputUserID){
        userID = inputUserID;
    }
    public void setPuzzleID(int inputPuzzleID){
        puzzleID = inputPuzzleID;
    }
    public int getUserID(){
        return userID;
    }
    //20100112
    public int getLangMode(){
        return langMode;
    }

    public int getPuzzleID(){
        return puzzleID;
    }
    // 20091016 phrase2 end

    /* game variables end ****************************************************************/
    // 2009P1T1 Ends

    /* Interface Model start *************************************************************/
    public void setTextLearnerStepsMsgBox(String inputDisplayStr){
        learnerStepsMsgBox.append(inputDisplayStr);
    }
    public void setTextSolvingStatus(int numberOfcellUnsolved){
        SolvingStatus.setText(Integer.toString(numberOfcellUnsolved));
    }
    public void setTextHintsStatus(int hintsLevel, int numberOfHints){
        HintsStatus[hintsLevel].setText(Integer.toString(numberOfHints));
    }
    public void setTextGameStatus(String inputGameStatus){
        GameStatus.setText(inputGameStatus);
    }
    public void setTextCellsValueLabel(int indexX, int indexY, int cellValue){
        if(cellValue!=0){
            cellsValueLabel[indexX][indexY].setText(Integer.toString(cellValue));
        }else{
            cellsValueLabel[indexX][indexY].setText("");
        }
    }
    public void setVisibleCaluCellsLabel(int indexX, int indexY, int indexK, boolean isVisible){
         caluCellsLabel[indexX][indexY][indexK].setVisible(isVisible);
    }
    public boolean isVisibleCaluCellsLabel(int indexX, int indexY, int indexK){
         return caluCellsLabel[indexX][indexY][indexK].isVisible();
    }
    /* for the text display in TextLearnerStepsMsgBox */
    /* DND*/
    public void setTextAssignCellValue(int inputIndexX, int inputIndexY, int inputCellValue){
        int RowIndex = inputIndexY + 1;
        int ColumnIndex = inputIndexX + 1;
        int cellValue = inputCellValue;
        if(this.getLangMode() == ENG_MODE ){
            this.setTextLearnerStepsMsgBox(
                "Cell(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\tASSIGNE\twith value\t" + cellValue + "\n"
                );
        }
        if(this.getLangMode() == CHIN_MODE ){
            this.setTextLearnerStepsMsgBox(
                "格(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\t指定\t答案\t" + cellValue + "\n"
                );
        }
    }
    public void setTextEraseCellValue(int inputIndexX, int inputIndexY, int inputCellValue){
        int RowIndex = inputIndexY + 1;
        int ColumnIndex = inputIndexX + 1;
        int cellValue = inputCellValue;
        if(this.getLangMode() == ENG_MODE ){
            this.setTextLearnerStepsMsgBox(
                "Cell(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\tERASE\twith value\t" + cellValue + "\n"
                );
        }
        if(this.getLangMode() == CHIN_MODE ){
            this.setTextLearnerStepsMsgBox(
                "格(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\t擦掉\t答案\t" + cellValue + "\n"
                );
        }
    }
    /* MOUSE Click*/
    public void setTextRecoverCaluCellValue(int inputIndexX, int inputIndexY, int inputInvolvedValue){
        int RowIndex = inputIndexY + 1;
        int ColumnIndex = inputIndexX + 1;
        int involvedValue = inputInvolvedValue;
        if(this.getLangMode() == ENG_MODE ){
            this.setTextLearnerStepsMsgBox(
                "Cell(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\tRECOVER\tpossible value\t" + involvedValue + "\n"
                );
        }
        if(this.getLangMode() == CHIN_MODE ){
            this.setTextLearnerStepsMsgBox(
                "格(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\t恢復\t可能答案\t" + involvedValue + "\n"
                );
        }
    }
    public void setTextEliminCaluCellValue(int inputIndexX, int inputIndexY, int inputInvolvedValue){
        int RowIndex = inputIndexY + 1;
        int ColumnIndex = inputIndexX + 1;
        int involvedValue = inputInvolvedValue;
        if(this.getLangMode() == ENG_MODE ){
            this.setTextLearnerStepsMsgBox(
                "Cell(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\tELIMINATE\tpossible value\t" + involvedValue + "\n"
                );
        }
        if(this.getLangMode() == CHIN_MODE ){
            this.setTextLearnerStepsMsgBox(
                "格(" + RowIndex+ ", "+  COLUMN_INDEX_ALPHA[ColumnIndex] +")\t淘汰\t可能答案\t" + involvedValue + "\n"
                );
        }
    }

    //2009P1T1 starts
    public void endGame(){
        /* Step 1: stop the timer */
        Timer.StopTimer();
        String timeUsed = Timer.getDisplayTime();
        /* Step 2: show the useful; variables */
        /*  variables list
         * 1    puzzleID (defined in ControlLayer)
         * 2    difficulty (defined in ControlLayer)
         * 3    rules priority (defined in ControlLayer)
         * 4    Time used (get from time label)
         * 5    Hints(different levels) used (defined in ControlLayer)
         * 6    solving steps (get from student model diagonsis)
         */

        StringBuffer gameSolvedInfo = new StringBuffer();
        gameSolvedInfo.append("\n");

        /* Puzzle ID */
        gameSolvedInfo.append("Puzzle ID:\n");
        gameSolvedInfo.append(puzzleID);
        gameSolvedInfo.append("\n\n");

        /* Difficulty */
        gameSolvedInfo.append("Difficulty\n");
        gameSolvedInfo.append(difficulty);
        gameSolvedInfo.append("\n\n");

        /* Rules Priority */
        gameSolvedInfo.append("Difficulty\n");
        for(int i=0; i<rulesPriority.length; i++){
            int priority = i+1;
            gameSolvedInfo.append(priority + ".\t");
            gameSolvedInfo.append(rulesPriority[i]);
            gameSolvedInfo.append("\n");
        }
        gameSolvedInfo.append("\n");

        /*Time Used*/
        gameSolvedInfo.append("Time Used:\n");
        gameSolvedInfo.append(timeUsed);
        gameSolvedInfo.append("\n\n");

        /*Hints Used*/
        gameSolvedInfo.append("Hints Used:\n");
        for(int i=0; i< HintsStatus.length; i++){
            int level = i+1;
            gameSolvedInfo.append("Level "+level+":\t");
            gameSolvedInfo.append(HintsStatus[i].getText());
            gameSolvedInfo.append("\n");
        }
        gameSolvedInfo.append("\n");

        /*Step 3: show content of user*/
        //this.setTextLearnerStepsMsgBox(gameSolvedInfo.toString());
        //JOptionPane.showConfirmDialog(null, gameSolvedInfo.toString(), "Game End", JOptionPane.YES_OPTION);

        if(this.langMode == CHIN_MODE){
            JOptionPane.showConfirmDialog(null, "數獨已完成", "數獨已完成", JOptionPane.YES_OPTION);
        }
        if(this.langMode == ENG_MODE){
            JOptionPane.showConfirmDialog(null, "Game End", "Game End", JOptionPane.YES_OPTION);
        }

        // 20091030 phrase2 start
        this.recordSkillsMatrix();
        // 20100118 recordMisconception
        dbManager.recordMisconception(this.getMisconceptionNum());
        // 20091030 phrase2 end
        /*Refresh the Game*/
        webSudoku.getAppletContext().showDocument(webSudoku.getDocumentBase(), "_self");

    }

    //2009P1T1 end
    
    // 20091017 phrase2 start
    public int getNumHintsUsed(int hintsIndex){
        return Integer.parseInt(HintsStatus[hintsIndex].getText());
    }
    public void addNumHintsUsed(int hintsLevel){
        int numOfHints = this.getNumHintsUsed(hintsLevel) + 1;
        HintsStatus[hintsLevel].setText(Integer.toString(numOfHints));
    }
    // 20091017 phrase2 end

    /* Interface Model end ***************************************************************/

    /* Student model start ***************************************************************/
    public boolean isUndoEnabled(){
        return studentModel.isUndoEnabled();
    }
    public boolean isRedoEnabled(){
        return studentModel.isRedoEnabled();
    }
    public String undoSteps(){
        return studentModel.undoSteps();
    }
    public String redoSteps(){
        return studentModel.redoSteps();
    }
    public int getCellPosition(String inputCommand){
        return studentModel.getCellPosition(inputCommand);
    }
    public String getActionCommand(String inputCommand){
        return studentModel.getActionCommand(inputCommand);
    }
    public int getInvolvedValue(String inputCommand){
        return studentModel.getInvolvedValue(inputCommand);
    }
    public void recordSteps(int inputCellIndex, int inputCellValue, String inputActionCommand){
        studentModel.recordSteps(inputCellIndex, inputCellValue, inputActionCommand);
    }

    // 20091029 phrase2 start
    public int getCorrectStepsCount(){
        return studentModel.getCorrectStepsCount();
    }
        // 20100118
    public int getMisconceptionNum(){
        return studentModel.getMisconceptionNum();
    }
    public void setMisconceptionNum(int value){
        studentModel.setMisconceptionNum(value);
    }


    // 20091029 phrase2 end
    /* Student model end *******************************************************************************/

    /* Tutor model start *******************************************************************************/
    public String getHints(int inputHintsLevel){
        return tutorModel.getHints(inputHintsLevel);
    }
    // 20091018 phrase2 start
    public String getAllRules(int indexX, int indexY){
        return tutorModel.getAllLogicalRule(indexX, indexY);
    }
    // 20091018 phrase2 end
    public void setupHintsGenerator(StrategyGraphUnit[][] inputSolvedPuzzle){
        final StrategyGraphUnit[][]  solvedPuzzle = inputSolvedPuzzle;
        tutorModel.setupHintsGenerator(solvedPuzzle);
    }
    // 20091019 phrase2 start
    public void setupStepsMatrix(StepsMatrix inputSkillsMatrix){
        final StepsMatrix stepsMatrix = inputSkillsMatrix;
        tutorModel.setupStepsMatrix(stepsMatrix);
    }
    // 20091019 phrase2 end
    public boolean isLearnerInputCorrect(int inputIndexX, int inputIndexY, int inputCellValue){
        return tutorModel.isLearnerInputCorrect(inputIndexX, inputIndexY, inputCellValue);
    }
    public boolean isLearnerInputAllCorrect(){
        return tutorModel.isLearnerInputAllCorrect();
    }
    // 20091112 phrase2 start
    public void reStartAutoHintsTimer(int inputHintsLevel){
        tutorModel.reStartAutoHintsTimer(inputHintsLevel);
    }
    public void isEnableAutoHints(boolean isEnabled){
        tutorModel.isEnableAutoHints(isEnabled);
    }
    public void setAutoHintsTimeOff(){
        tutorModel.setAutoHintsTimerOff();
    }

    // 20091112 phrase2 start
    /* hints flag true - the value is generated by hints */
    /*            false - value come from user */
    public void setCellValueBySystem(int dropIndexX, int dropIndexY, int dropDataValue, String actionCommand, boolean hintsFlag){

        /* if answer is solve by hints, then giving another color for the value*/
        if(hintsFlag){
            cellsValueLabel[dropIndexX][dropIndexY].setForeground(SudokuComponentsProperties.getColorCellValueByHintsForeground());
        }

        /* Update UI */
        cellsValueLabel[dropIndexX][dropIndexY].setText(Integer.toString(dropDataValue));
        for(int i=0; i<NUM_CELLS_IN_UNIT; i++){
            this.setVisibleCaluCellsLabel(dropIndexX, dropIndexY, i, SudokuComponentsProperties.getIsFalse());
        }
        //this.setTextAssignCellValue(dropIndexX, dropIndexY, dropDataValue);

        /* UI Step 2 : update gameboard */
        Gameboard.setCellValue(dropIndexX, dropIndexY, dropDataValue);

        boolean isInputCorrect = this.isLearnerInputCorrect(dropIndexX, dropIndexY, dropDataValue);
        final boolean isInputAllCorrect = this.isLearnerInputAllCorrect();
        if(isInputCorrect && isInputAllCorrect){
            if(this.getLangMode() == ENG_MODE){
                this.setTextGameStatus(GAME_STATUS_CORRECT);
            }
            if(this.getLangMode() == CHIN_MODE){
                this.setTextGameStatus(GAME_STATUS_CORRECT_IN_CHIN);
            }
        }else{
            if(this.getLangMode() == ENG_MODE){
                this.setTextGameStatus(GAME_STATUS_WRONG);
            }
            if(this.getLangMode() ==CHIN_MODE){
                this.setTextGameStatus(GAME_STATUS_WRONG_IN_CHIN);
            }
        }
        
        this.setCellDefiniteValue(dropIndexX, dropIndexY, dropDataValue);

        this.setRuleUsed(dropIndexX, dropIndexY, this.getAllRules(dropIndexX, dropIndexY));

        this.setTextSolvingStatus(this.getNumCellsUnsolved());
        this.setupStepsMatrix(this.applyLogicalRules());

        int index = IndexConverter.getIndex(dropIndexX, dropIndexY);
        this.recordSteps(index, dropDataValue, actionCommand);

        this.solvePuzzle();
        this.reocrdStepsMatrix(this.getCorrectStepsCount());
        this.reStartAutoHintsTimer(-1);

        if(this.getNumCellsUnsolved()== 0){
            this.setAutoHintsTimeOff();
            //this.recordSkillsMatrix();
            this.endGame();
        }
    }

    public void setCellElminBySystem(StrategyGraphUnit involvedUnit, int involvedValue, int hintsFlg){

        int IRindex = (involvedUnit.getLogicalRule().equalsIgnoreCase( LOGICAL_RULES[ExpertModelProperties.getIntersectReductIndex()]))?1:0;
        int NPindex = (involvedUnit.getLogicalRule().equalsIgnoreCase( LOGICAL_RULES[ExpertModelProperties.getNakedPairsIndex()]))?1:0;
        int HPindex = (involvedUnit.getLogicalRule().equalsIgnoreCase( LOGICAL_RULES[ExpertModelProperties.getHiddenPairsIndex()]))?1:0;
        int gridID = IndexConverter.getIndex(involvedUnit.getColumnIndex(), involvedUnit.getRowIndex());
        if(!dbManager.recordElminEntries(gridID, involvedValue, IRindex, NPindex, HPindex, hintsFlg)){
            dbManager.recordError(this.getClass().getName().toString(), "cannot record hte cell eliminated by system ", DateTime.getTimestamp());
        }
    }
    // 20091112 phrase2 end

     public boolean isElminHintsCell(StrategyGraphUnit checkUnit){
         return tutorModel.isElminHintsCell(checkUnit);
     }
     public StrategyGraphUnit getElminHintsCell(StrategyGraphUnit checkUnit){
         return tutorModel.getElminHintsCell(checkUnit);
     }

    /* Tutor model end*******************************************************************************/

    /* Expert model start*******************************************************************************/
    public boolean getDefiniteValueSet(int inputIndexX, int inputIndexY){
        return expertModel.getDefiniteValueSet(inputIndexX, inputIndexY);
    }
    public Integer[] getDifficultyRange(int inputDifficultyIndex){
        return expertModel.getDifficultyRange(inputDifficultyIndex);
    }
    public int getNumCellsUnsolved(){
        return expertModel.getNumCellsUnsolved();
    }
    // 20091112 phrase2 start
    public String getGameDifficulty(){
        return expertModel.getGameDifficulty();
    }
    // 20091112 phrase2 end
    public String getSGSolvingProcedure(StrategyGraphUnit inputSolvingUnit){
        return expertModel.getSGSolvingProcedure(inputSolvingUnit);
    }
    public String getNSSolvingProcedure(StrategyGraphUnit inputSolvingUnit){
        return expertModel.getNSSolvingProcedure(inputSolvingUnit);
    }
    public String getHSSolvingProcedure(StrategyGraphUnit inputSolvingUnit){
        return expertModel.getHSSolvingProcedure(inputSolvingUnit);
    }
    public String getIRSolvingProcedure(StrategyGraphUnit inputSolvingUnit, int[] valuesInvolved){
        return expertModel.getIRSolvingProcedure(inputSolvingUnit, valuesInvolved);
    }
    public String getNPSolvingProcedure(StrategyGraphUnit inputSolvingUnit, int[] valuesInvolved){
        return expertModel.getNPSolvingProcedure(inputSolvingUnit, valuesInvolved);
    }
    public String getHPSolvingProcedure(StrategyGraphUnit inputSolvingUnit, int[] valuesInvolved){
        return expertModel.getHPSolvingProcedure(inputSolvingUnit, valuesInvolved);
    }

    // 20090111
    public String getSGSolvingProcedureInChinese(StrategyGraphUnit inputSolvingUnit){
        return expertModel.getSGSolvingProcedureInChinese(inputSolvingUnit);
    }
    public String getNSSolvingProcedureInChinese(StrategyGraphUnit inputSolvingUnit){
        return expertModel.getNSSolvingProcedureInChinese(inputSolvingUnit);
    }
    public String getHSSolvingProcedureInChinese(StrategyGraphUnit inputSolvingUnit){
        return expertModel.getHSSolvingProcedureInChinese(inputSolvingUnit);
    }
    public String getIRSolvingProcedureInChinese(StrategyGraphUnit inputSolvingUnit, int[] valuesInvolved){
        return expertModel.getIRSolvingProcedureInChinese(inputSolvingUnit, valuesInvolved);
    }
    public String getNPSolvingProcedureInChinese(StrategyGraphUnit inputSolvingUnit, int[] valuesInvolved){
        return expertModel.getNPSolvingProcedureInChinese(inputSolvingUnit, valuesInvolved);
    }
    public String getHPSolvingProcedureInChinese(StrategyGraphUnit inputSolvingUnit, int[] valuesInvolved){
        return expertModel.getHPSolvingProcedureInChinese(inputSolvingUnit, valuesInvolved);
    }

    public void removeDefiniteValue(int inputIndexX, int inputIndexY){
        expertModel.removeDefiniteValue(inputIndexX, inputIndexY);
    }
    public void setDifficultyLevel(String inputDifficultyLevel){
        expertModel.setDifficultyLevel(inputDifficultyLevel);
    }
    public void setGivenCellDefiniteValue(int inputIndexX, int inputIndexY, int inputCellValue){
        expertModel.setGivenCellDefiniteValue(inputIndexX, inputIndexY, inputCellValue);
    }
    public void setNumGivenCells(int inputNumGivenCells){
        expertModel.setNumGivenCells(inputNumGivenCells);
    }
    public int[] getInvolvedValue(StrategyGraphUnit involvedCell){
        return expertModel.getInvolvedValue(involvedCell);
    }
    // 20091017 phrase2 start
    public String getRuleUsed(int inputIndexX, int inputIndexY){
        return expertModel.getRuleUsed(inputIndexX, inputIndexY);
    }

    public void setRuleUsed(int inputIndexX,int inputIndexY, String rule){
        expertModel.setRuleUsed(inputIndexX, inputIndexY, rule);
    }
    // 20091017 phrase2 end
    public void setCellDefiniteValue(int inputIndexX, int inputIndexY, int inputCellValue){
        expertModel.setCellDefiniteValue(inputIndexX, inputIndexY, inputCellValue);
    }
    // for testing
    // 20091019 phrase2 start
    public StepsMatrix applyLogicalRules(){
        return expertModel.applyLogicalRules();
    }
    // 20091019 phrase2 end
    public StrategyGraphUnit[][] solvePuzzle(){
        return expertModel.solvePuzzle();
    }

    // 20091029 phrase2 start
    public void reocrdStepsMatrix(int stepCount){
        expertModel.recordStepsMatrix(stepCount);
    }
    public void recordSkillsMatrix(){
        expertModel.recordSkillsMatrix();
    }

    // testing
    public StrategyGraphUnit getStrategyUnit(int indexX, int indexY){
        return expertModel.getStrategyUnit(indexX, indexY);
    }
    // 20091029 phrase2 end

    /* Expert model end*********************************************************************************/

    /* Mixed model start************************************************************************************/
    public void setRulesRanking(ArrayList<Integer> inputRulesRanking){
        tutorModel.setRulesRanking(inputRulesRanking);
        //expertModel.setRulesRanking(inputRulesRanking);
    }
    // 20100126
    public ArrayList<Integer> getRulesRanking(){
        return tutorModel.getRulesRanking();
    }
    /*Mxixed model end***************************************************************************************/

    /*ITS models */
    private StudentModel studentModel;
    private ExpertModel expertModel;
    private TutorModel tutorModel;

    /* the interface components which need to change during game*/
    private JLabel[][][] caluCellsLabel;
    private JLabel[][] cellsValueLabel;
    private JTextArea learnerStepsMsgBox;
    private JLabel SolvingStatus;
    private JLabel[] HintsStatus;
    private JLabel GameStatus;
    private TimerHandler Timer;
    private int userID;
    private int langMode;

    // 2009P1T1 starts
    /* game variables */
    private int puzzleID;
    private String difficulty;
    private String[] rulesPriority;
    private JApplet webSudoku;
    // 2009P1T1 ends

    // 20091112 phrase2 start
    private SudokuGameboard Gameboard;
    private DatabaseManager dbManager;
    // 20091112 phrase2 end

    /* Constant variables */
    final int NUM_CELLS_IN_UNIT = BasicSudokuParam.getNumCellsInUnit();
    final String[] COLUMN_INDEX_ALPHA = SudokuGameInfoParam.getColumnIndexAlpha();
    final String[] HINTS_LEVEL = SudokuGameInfoParam.getHintsLevel();
    final String[] LOGICAL_RULES = SudokuGameInfoParam.getLogicalRules();
    final String GAME_STATUS_CORRECT = SudokuGameInfoParam.getGameStatusCorrrect();
    final String GAME_STATUS_WRONG = SudokuGameInfoParam.getGameStatusWrong();
    final String GAME_STATUS_CORRECT_IN_CHIN = SudokuGameInfoParam.getGameStatusCorrrectInChin();
    final String GAME_STATUS_WRONG_IN_CHIN = SudokuGameInfoParam.getGameStatusWrongInChin();
    final int ENG_MODE = SudokuGameInfoParam.getEnglishMode();
    final int CHIN_MODE = SudokuGameInfoParam.getChineseMode();
}


